package link.luyu.plugin.brochain.web3.methods.response;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigInteger;
import java.util.List;
import org.web3j.utils.Numeric;

public class Page {

    @JsonProperty("blocknumber")
    private String blockNumber;

    @JsonProperty("regionid")
    private String regionId;

    @JsonProperty("regionPageHash")
    private String hash;

    @JsonProperty("regionPreviousPagehash")
    private String parentHash;

    @JsonProperty("regionNextPagehash")
    private String childHash;

    @JsonProperty("regionTransactionsRoot")
    private String transactionsRoot;

    @JsonProperty("regionStateRoot")
    private String stateRoot;
    //    @JsonProperty("regionReceiptsRoot")
    //    private String receiptsRoot;
    private String timestamp;
    private List<PageTransaction> transactions;

    public Page() {}

    public Page(
            String blockNumber,
            String regionId,
            String hash,
            String parentHash,
            String childHash,
            String transactionsRoot,
            String stateRoot,
            //            String receiptsRoot,
            String timestamp,
            List<PageTransaction> transactions) {
        this.blockNumber = blockNumber;
        this.regionId = regionId;
        this.hash = hash;
        this.parentHash = parentHash;
        this.childHash = childHash;
        this.transactionsRoot = transactionsRoot;
        this.stateRoot = stateRoot;
        //        this.receiptsRoot = receiptsRoot;
        this.timestamp = timestamp;
        this.transactions = transactions;
    }

    public BigInteger getBlockNumber() {
        return Numeric.decodeQuantity(blockNumber);
    }

    public String getBlockNumberRaw() {
        return blockNumber;
    }

    public void setBlockNumber(String blockNumber) {
        this.blockNumber = blockNumber;
    }

    public String getRegionId() {
        return regionId;
    }

    public void setRegionId(String regionId) {
        this.regionId = regionId;
    }

    public String getHash() {
        return hash;
    }

    public void setHash(String hash) {
        this.hash = hash;
    }

    public String getParentHash() {
        return parentHash;
    }

    public void setParentHash(String parentHash) {
        this.parentHash = parentHash;
    }

    public String getChildHash() {
        return childHash;
    }

    public void setChildHash(String childHash) {
        this.childHash = childHash;
    }

    public String getTransactionsRoot() {
        return transactionsRoot;
    }

    public void setTransactionsRoot(String transactionsRoot) {
        this.transactionsRoot = transactionsRoot;
    }

    public String getStateRoot() {
        return stateRoot;
    }

    public void setStateRoot(String stateRoot) {
        this.stateRoot = stateRoot;
    }

    //    public String getReceiptsRoot() {
    //        return receiptsRoot;
    //    }

    //    public void setReceiptsRoot(String receiptsRoot) {
    //        this.receiptsRoot = receiptsRoot;
    //    }

    public BigInteger getTimestamp() {
        return Numeric.decodeQuantity(timestamp);
    }

    public String getTimestampRaw() {
        return timestamp;
    }

    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }

    public List<PageTransaction> getTransactions() {
        return transactions;
    }

    public void setTransactions(List<PageTransaction> transactions) {
        this.transactions = transactions;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof Page)) {
            return false;
        }

        Page page = (Page) o;

        if (getBlockNumberRaw() != null
                ? !getBlockNumberRaw().equals(page.getBlockNumberRaw())
                : page.getBlockNumberRaw() != null) {
            return false;
        }
        if (getRegionId() != null
                ? !getRegionId().equals(page.getRegionId())
                : page.getRegionId() != null) {
            return false;
        }
        if (getHash() != null ? !getHash().equals(page.getHash()) : page.getHash() != null) {
            return false;
        }
        if (getParentHash() != null
                ? !getParentHash().equals(page.getParentHash())
                : page.getParentHash() != null) {
            return false;
        }
        if (getChildHash() != null
                ? !getChildHash().equals(page.getChildHash())
                : page.getChildHash() != null) {
            return false;
        }
        if (getTransactionsRoot() != null
                ? !getTransactionsRoot().equals(page.getTransactionsRoot())
                : page.getTransactionsRoot() != null) {
            return false;
        }
        if (getStateRoot() != null
                ? !getStateRoot().equals(page.getStateRoot())
                : page.getStateRoot() != null) {
            return false;
        }
        //        if (getReceiptsRoot() != null
        //                ? !getReceiptsRoot().equals(page.getReceiptsRoot())
        //                : page.getReceiptsRoot() != null) {
        //            return false;
        //        }
        if (getTimestampRaw() != null
                ? !getTimestampRaw().equals(page.getTimestampRaw())
                : page.getTimestampRaw() != null) {
            return false;
        }
        return getTransactions() != null
                ? getTransactions().equals(page.getTransactions())
                : page.getTransactions() == null;
    }

    @Override
    public int hashCode() {
        int result = getBlockNumberRaw() != null ? getBlockNumberRaw().hashCode() : 0;
        result = 31 * result + (getRegionId() != null ? getRegionId().hashCode() : 0);
        result = 31 * result + (getHash() != null ? getHash().hashCode() : 0);
        result = 31 * result + (getParentHash() != null ? getParentHash().hashCode() : 0);
        result = 31 * result + (getChildHash() != null ? getChildHash().hashCode() : 0);
        result =
                31 * result
                        + (getTransactionsRoot() != null ? getTransactionsRoot().hashCode() : 0);
        result = 31 * result + (getStateRoot() != null ? getStateRoot().hashCode() : 0);
        //        result = 31 * result + (getReceiptsRoot() != null ? getReceiptsRoot().hashCode() :
        // 0);
        result = 31 * result + (getTimestampRaw() != null ? getTimestampRaw().hashCode() : 0);
        result = 31 * result + (getTransactions() != null ? getTransactions().hashCode() : 0);
        return result;
    }

    public static class PageTransaction {

        @JsonProperty("transactionHash")
        private String hash;

        private String nonce;
        private String from;
        private String to;

        @JsonProperty("blocklimit")
        private String blockLimit;

        @JsonProperty("data")
        private String input;

        private String publicKey;
        private String raw;
        private String r;
        private String s;
        private long v;

        private List<Log> logs;

        public PageTransaction() {}

        public PageTransaction(
                String hash,
                String nonce,
                String from,
                String to,
                String blockLimit,
                String input,
                String publicKey,
                String raw,
                String r,
                String s,
                long v) {
            this.hash = hash;
            this.nonce = nonce;
            this.from = from;
            this.to = to;
            this.blockLimit = blockLimit;
            this.input = input;
            this.publicKey = publicKey;
            this.raw = raw;
            this.r = r;
            this.s = s;
            this.v = v;
        }

        public PageTransaction(
                String hash,
                String nonce,
                String from,
                String to,
                String blockLimit,
                String input,
                String publicKey,
                String raw,
                String r,
                String s,
                long v,
                List<Log> logs) {
            this(hash, nonce, from, to, blockLimit, input, publicKey, raw, r, s, v);
            this.logs = logs;
        }

        public String getHash() {
            return hash;
        }

        public void setHash(String hash) {
            this.hash = hash;
        }

        public BigInteger getNonce() {
            return Numeric.decodeQuantity(nonce);
        }

        public String getNonceRaw() {
            return nonce;
        }

        public void setNonce(String nonce) {
            this.nonce = nonce;
        }

        public String getFrom() {
            return from;
        }

        public void setFrom(String from) {
            this.from = from;
        }

        public String getTo() {
            return to;
        }

        public void setTo(String to) {
            this.to = to;
        }

        public BigInteger getBlockLimit() {
            return Numeric.decodeQuantity(blockLimit);
        }

        public String getBlockLimitRaw() {
            return blockLimit;
        }

        public void setBlockLimit(String blockLimit) {
            this.blockLimit = blockLimit;
        }

        public String getInput() {
            return input;
        }

        public void setInput(String input) {
            this.input = input;
        }

        public String getPublicKey() {
            return publicKey;
        }

        public void setPublicKey(String publicKey) {
            this.publicKey = publicKey;
        }

        public String getRaw() {
            return raw;
        }

        public void setRaw(String raw) {
            this.raw = raw;
        }

        public String getR() {
            return r;
        }

        public void setR(String r) {
            this.r = r;
        }

        public String getS() {
            return s;
        }

        public void setS(String s) {
            this.s = s;
        }

        public long getV() {
            return v;
        }

        // public void setV(byte v) {
        //     this.v = v;
        // }

        public List<Log> getLogs() {
            return logs;
        }

        public void setLogs(List<Log> logs) {
            this.logs = logs;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (!(o instanceof PageTransaction)) {
                return false;
            }

            PageTransaction that = (PageTransaction) o;

            if (getV() != that.getV()) {
                return false;
            }
            if (getHash() != null ? !getHash().equals(that.getHash()) : that.getHash() != null) {
                return false;
            }
            if (getNonceRaw() != null
                    ? !getNonceRaw().equals(that.getNonceRaw())
                    : that.getNonceRaw() != null) {
                return false;
            }
            if (getFrom() != null ? !getFrom().equals(that.getFrom()) : that.getFrom() != null) {
                return false;
            }
            if (getTo() != null ? !getTo().equals(that.getTo()) : that.getTo() != null) {
                return false;
            }
            if (getBlockLimitRaw() != null
                    ? !getBlockLimitRaw().equals(that.getBlockLimitRaw())
                    : that.getBlockLimitRaw() != null) {
                return false;
            }
            if (getInput() != null
                    ? !getInput().equals(that.getInput())
                    : that.getInput() != null) {
                return false;
            }
            if (getPublicKey() != null
                    ? !getPublicKey().equals(that.getPublicKey())
                    : that.getPublicKey() != null) {
                return false;
            }
            if (getRaw() != null ? !getRaw().equals(that.getRaw()) : that.getRaw() != null) {
                return false;
            }
            if (getR() != null ? !getR().equals(that.getR()) : that.getR() != null) {
                return false;
            }
            if (getS() != null ? !getS().equals(that.getS()) : that.getS() != null) {
                return false;
            }
            return getLogs() != null ? getLogs().equals(that.getLogs()) : that.getLogs() == null;
        }

        @Override
        public int hashCode() {
            int result = getHash() != null ? getHash().hashCode() : 0;
            result = 31 * result + (getNonceRaw() != null ? getNonceRaw().hashCode() : 0);
            result = 31 * result + (getFrom() != null ? getFrom().hashCode() : 0);
            result = 31 * result + (getTo() != null ? getTo().hashCode() : 0);
            result = 31 * result + (getBlockLimitRaw() != null ? getBlockLimitRaw().hashCode() : 0);
            result = 31 * result + (getInput() != null ? getInput().hashCode() : 0);
            result = 31 * result + (getPublicKey() != null ? getPublicKey().hashCode() : 0);
            result = 31 * result + (getRaw() != null ? getRaw().hashCode() : 0);
            result = 31 * result + (getR() != null ? getR().hashCode() : 0);
            result = 31 * result + (getS() != null ? getS().hashCode() : 0);
            result = 31 * result + BigInteger.valueOf(getV()).hashCode();
            result = 31 * result + (getLogs() != null ? getLogs().hashCode() : 0);
            return result;
        }
    }
}
